package com.cdks.wuxiu.api.controller;

import com.cdks.wuxiu.api.component.constant.Constant;
import com.cdks.wuxiu.api.model.param.BookConfirmParam;
import com.cdks.wuxiu.api.model.param.BookCreateParam;
import com.cdks.wuxiu.api.model.param.BookFinishParam;
import com.cdks.wuxiu.api.model.param.BookParamsParam;
import com.cdks.wuxiu.api.model.param.BookPayParam;
import com.cdks.wuxiu.api.model.param.BookQueryParam;
import com.cdks.wuxiu.api.model.param.BookRecordParam;
import com.cdks.wuxiu.api.model.param.BookSignInParam;
import com.cdks.wuxiu.api.service.BookService;
import com.cdks.wuxiu.api.service.MessageService;
import com.cdks.wuxiu.api.service.UserService;
import com.cdks.wuxiu.api.util.SmsUtils;
import com.cdks.wuxiu.api.util.TimeUtils;
import com.cdks.wuxiu.common.model.api.ApiResult;
import com.cdks.wuxiu.entity.message.ChatPrivateData;
import com.cdks.wuxiu.entity.mysql.BookConsultInfo;
import com.cdks.wuxiu.entity.mysql.UserBaseInfo;

import cn.hutool.json.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

import javax.annotation.Resource;
import javax.validation.Valid;


@Api(tags = "预约")
@Slf4j
@RestController
@RequestMapping("/book")
public class BookController {
    @Resource
    private BookService bookService;
    @Resource
    private UserService userService;
    @Resource
    private MessageService messageService; 


    private BookConsultInfo checkBook(long userId, long nowTime, long startTime, long expireTime)
    {
        //查找是否有同时段的预约咨询单
        BookConsultInfo order  = bookService.getPlanSheetByUser(userId, startTime, expireTime);
        if (order == null)
        {
            return null;
        }

        //已超过截止时间，并且未完成支付或已开始，自动结束
        if ((nowTime > order.getExpireTime()) && (order.getStatus() != Constant.BOOK_STATUS_PAYED))
        {
            order.setFinishStatus(Constant.BOOK_FINISH_SYSTEM);
            order.setRemark("订单超时自动关闭");
            order.setStatus(Constant.BOOK_STATUS_DROP);
            order.setStopTime(nowTime);
            int ret = bookService.finishSheet(order);
            if (ret == 0)
            {
                ChatPrivateData info  = new ChatPrivateData();

                info.setContent("【温馨提醒】您的预约咨询订单因超时已自动关闭。请前往查看。");
                info.setTitle("点击这里立即前往");
                info.setScheme("xinsu://book/detail?orderNo=" + order.getOrderNo());
                messageService.sendSystemMessage(order.getPayer(), Constant.MSG_TYPE_LINK, info);
                messageService.sendSystemMessage(order.getEarner(), Constant.MSG_TYPE_LINK, info);
            }
            
            return null;
        }

        return order;
    }

    @ApiOperation("获取参数")
    @PostMapping("/params")
    public ApiResult<Object> params(@RequestBody @Valid BookParamsParam param) {
        int price  = param.getUserInfo().getTextPrice();
        int role  = Constant.BOOK_ROLE_PAYER;
        UserBaseInfo recver  = userService.getUserById(param.getRecverId());

        if (recver.getAuthRole().equals(param.getUserInfo().getAuthRole()))
        {
            return ApiResult.failed(10, "对方未开通此功能");
        }

        if (recver.getAuthRole() < param.getUserInfo().getAuthRole())
        {
            role   = Constant.BOOK_ROLE_EARNER;
            price  = param.getUserInfo().getTextPrice();
        }
        else
        {
            role   = Constant.BOOK_ROLE_PAYER;
            price  = recver.getTextPrice();                
        }

        int[] times = {30, 60}; 
        String[] rules  = {
            "1、预约需要支付定金，爽约者定金只退50%",
            "2、所付定金仅为预约时段内的纯文字聊天每分钟的收费价格，若咨询时段内仅纯文字聊天不需另外付费，语音通话将根据实际收费标准实时付费",
            "3、所预约的咨询服务以双方签到为开始，截止预约时段结束仍未签到者视为爽约。未爽约者定金全额退款，并获得爽约者所支付定金50%的补偿",
            "4、咨询服务以预约的时段计费。咨询服务开始后若提前结束，按实际服务时长计费",
            "5、距预约服务开始前十分钟可签到，不足一小时不可取消"
        };
   
        JSONObject json  = new JSONObject();
        json.set("price", price);
        json.set("times", times);
        json.set("rules", rules);
        json.set("role", role);

        return ApiResult.success(json);
    }
    
    @ApiOperation("预约建单")
    @PostMapping("/create")
    public ApiResult<Object> create(@RequestBody @Valid BookCreateParam param) {
        UserBaseInfo recver  = userService.getUserById(param.getRecverId());
        if (!recver.getType().equals(param.getUserInfo().getType()))
        {
            return ApiResult.failed(10, "对方未开通此功能");
        }

        int cost  = param.getPrice() * param.getMinutes();
        long nowTime  = TimeUtils.getTimeSecond();
        String orderNo   = "XSB" + TimeUtils.getLocalDateTime("yyyyMMddHHmmssSSS") + param.getUserId();
        BookConsultInfo order  = new BookConsultInfo();
        order.setCreateTime(nowTime);
        order.setOrderNo(orderNo);
        order.setMinutes(param.getMinutes());
        order.setPrice(param.getPrice());
        order.setCost(cost);
        order.setSignInStatus(Constant.BOOK_SIGNIN_NONE);
        order.setStatus(Constant.BOOK_STATUS_NOPAY);

        //收益方建单必须上传时间和内容
        if (param.getRole() == Constant.BOOK_ROLE_EARNER)
        {
            if ((param.getTime() == null) || param.getContent() == null)
            {
                return ApiResult.failed(10, "请填写预定开始时间和预约内容");
            }

            long sartTime  = (param.getTime() - nowTime) < 300 ? (nowTime + 300) : param.getTime();
            order.setPayer(param.getRecverId());
            order.setEarner(param.getUserId());
            order.setStartTime(sartTime);
            order.setExpireTime(sartTime + param.getMinutes() * 60);
            order.setContent(param.getContent());
            order.setSurety(0);
            order.setPayStatus(Constant.BOOK_PAYED_EARNER);

            //查找双方在预约时间是否已有预约服务
            BookConsultInfo plan  = bookService.getPlanSheetAnyUser(param.getUserId(), param.getRecverId(), order.getStartTime(), order.getExpireTime());
            if (plan != null)
            {
                //已超过截止时间，并且未完成支付或已开始，自动结束
                if ((nowTime > plan.getExpireTime()) && (plan.getStatus() != Constant.BOOK_STATUS_PAYED))
                {
                    plan.setFinishStatus(Constant.BOOK_FINISH_SYSTEM);
                    plan.setRemark("订单超时自动关闭");
                    plan.setStatus(Constant.BOOK_STATUS_DROP);
                    plan.setStopTime(nowTime);
                    int ret = bookService.finishSheet(plan);
                    if (ret == 0)
                    {
                        ChatPrivateData info  = new ChatPrivateData();

                        info.setContent("【温馨提醒】您的预约咨询订单因超时已自动关闭。请前往查看。");
                        info.setTitle("点击这里立即前往");
                        info.setScheme("xinsu://book/detail?orderNo=" + plan.getOrderNo());
                        messageService.sendSystemMessage(plan.getPayer(), Constant.MSG_TYPE_LINK, info);
                        messageService.sendSystemMessage(plan.getEarner(), Constant.MSG_TYPE_LINK, info);
                    }
                }
                else
                {    
                    log.info("book create failed: " + plan);

                    if (param.getUserId().equals(plan.getPayer()) || param.getUserId().equals(plan.getEarner()))
                    {
                        return ApiResult.failed(10, "建单失败，您在该时段已有预约");
                    }
                    else
                    {
                        return ApiResult.failed(10, "建单失败，对方在该时段已有预约");
                    }
                }
            }

            int ret  = bookService.payCost(param.getUserId(), order.getSurety(), 0, "预约咨询押金");
            if (ret < 0)
            {
                ChatPrivateData info  = new ChatPrivateData();
                info.setContent("余额不足，预约失败，请前往充值");
                info.setScheme("xinsu://bean/recharge"); 
                messageService.sendSystemMessage(param.getUserId(), Constant.MSG_TYPE_POPUP, info);

                return ApiResult.failed(10, "余额不足，请先充值");
            }
        }
        else
        {
            order.setPayer(param.getUserId());
            order.setEarner(param.getRecverId());
            order.setPayStatus(Constant.BOOK_PAYED_PAYER);

            int ret  = bookService.payCost(param.getUserId(), order.getCost(), 0, "预约咨询定金");
            if (ret < 0)
            {
                ChatPrivateData info  = new ChatPrivateData();
                info.setContent("余额不足，预约失败，请前往充值");
                info.setScheme("xinsu://bean/recharge"); 
                messageService.sendSystemMessage(param.getUserId(), Constant.MSG_TYPE_POPUP, info);

                return ApiResult.failed(10, "余额不足，请先充值");
            }
        }

        int ret = bookService.createSheet(order);
        if (ret < 0)
        {
            return ApiResult.failed(10, "创建预约失败");
        }

        //已到开始时间，自动签到
        if ((order.getStartTime() != null) && ((order.getStartTime() - nowTime) < Constant.TIME_VALUE_10_MINUTES))
        {
            bookService.autoSignIn(order, param.getUserId());
        }

        //发送预约消息
        ChatPrivateData info  = new ChatPrivateData();
        info.setStartTime(order.getStartTime());
        info.setMinutes(order.getMinutes());
        info.setCost(cost);
        info.setOrderNo(orderNo);
        info.setStatus(order.getStatus());
        info.setContent("咨询服务预约单待确认");
        messageService.sendUserMessage(param.getUserId(), param.getRecverId(), Constant.MSG_TYPE_BOOK, info, true);
        messageService.sendOfflineNotice(param.getRecverId(), "【预约咨询】", "咨询服务预约单待确认");
   
        JSONObject json  = new JSONObject();
        json.set("orderNo", order.getOrderNo());

        //发送短信通知
        SmsUtils.sendManageNotice("用户" + param.getUserId() + "对" + param.getRecverId() + "发起了预约");

        return ApiResult.success(json);
    }

    @ApiOperation("支付定金")
    @PostMapping("/payCost")
    public ApiResult<Object> payCost(@RequestBody @Valid BookPayParam param) {
        BookConsultInfo order  = bookService.getSheetByOrderNo(param.getOrderNo());
        if (order == null)
        {
            return ApiResult.failed(10, "预约单不存在");
        }

        long nowTime  = TimeUtils.getTimeSecond();
        BookConsultInfo plan  = checkBook(param.getUserId(), nowTime, order.getStartTime(), order.getExpireTime());
        if ((plan != null) && (!order.getOrderNo().equals(plan.getOrderNo())))
        {
            log.info("book create failed: " + plan);

            return ApiResult.failed(10, "支付失败，您在该时段已有预约");
        }

        if (param.getUserId().equals(order.getEarner()))
        {
            return ApiResult.failed(10, "无权限");
        }

        if ((order.getPayStatus() & Constant.BOOK_PAYED_PAYER) > 0)
        {
            return ApiResult.failed(10, "定金已支付");
        }

        if (order.getStatus() > Constant.BOOK_STATUS_NOPAY)
        {
            return ApiResult.failed(10, "该预约单不可支付");
        }

        //当前时间超过服务预定结束时间不可支付
        if (nowTime > order.getExpireTime())
        {
            return ApiResult.failed(10, "已超过预定结束时间，订单不可支付，请先结束订单重新预约");
        }

        log.info("book payCost: order = " + order);

        int ret  = bookService.payCost(param.getUserId(), order.getCost(), order.getId(), "预约咨询定金");
        if (ret < 0)
        {
            ChatPrivateData info  = new ChatPrivateData();
            info.setContent("余额不足，支付失败，请前往充值");
            info.setScheme("xinsu://bean/recharge"); 
            messageService.sendSystemMessage(param.getUserId(), Constant.MSG_TYPE_POPUP, info);

            return ApiResult.failed(10, "预约单支付失败");
        }

        order.setPayStatus(order.getPayStatus() | Constant.BOOK_PAYED_PAYER);
        order.setStatus(Constant.BOOK_STATUS_PAYED);

        ret  = bookService.paySheet(order);
        if (ret < 0)
        {
            log.error("book payCost failed : order = " + order);
        }

        //已到开始时间，自动签到
        if ((order.getStartTime() - nowTime) < Constant.TIME_VALUE_10_MINUTES)
        {
            bookService.autoSignIn(order, param.getUserId());
        }

        //发送预约消息
        ChatPrivateData info  = new ChatPrivateData();
        info.setStartTime(order.getStartTime());
        info.setMinutes(order.getMinutes());
        info.setCost(order.getCost());
        info.setOrderNo(order.getOrderNo());
        info.setStatus(order.getStatus());
        info.setContent("咨询服务预约单已支付");
        messageService.sendUserMessage(order.getPayer(), order.getEarner(), Constant.MSG_TYPE_BOOK, info, true); 
        messageService.sendOfflineNotice(order.getEarner(), "【预约咨询】", "咨询服务预约单已支付");           

        return ApiResult.success();
    }

    @ApiOperation("预约确认")
    @PostMapping("/confirm")
    public ApiResult<Object> confirm(@RequestBody @Valid BookConfirmParam param) {
        BookConsultInfo order  = bookService.getSheetByOrderNo(param.getOrderNo());
        if (order == null)
        {
            return ApiResult.failed(10, "预约单不存在");
        }

        if (param.getUserId().equals(order.getPayer()))
        {
            return ApiResult.failed(10, "无权限");
        }

        if ((order.getPayStatus() & Constant.BOOK_PAYED_EARNER) > 0)
        {
            return ApiResult.failed(10, "押金已支付");
        }

        if (order.getStatus() != Constant.BOOK_STATUS_NOPAY)
        {
            return ApiResult.failed(10, "预约单状态异常，请联系客服");
        }

        //当前时间超过服务预定开始时间不可确认
        if ((order.getStartTime() > 0) && (TimeUtils.getTimeSecond() > order.getStartTime()))
        {
            //发送弹窗提示
            ChatPrivateData info  = new ChatPrivateData();
            info.setContent("已超过预定开始时间，订单不可确认。请先与用户协商，更改预约时间");
            info.setScheme("xinsu://book/detail?orderNo=" + order.getOrderNo());
            messageService.sendSystemMessage(param.getUserId(), Constant.MSG_TYPE_POPUP, info); 

            return ApiResult.failed(10, "请求失败");
        }

        order.setStartTime(param.getTime());
        order.setExpireTime(param.getTime() + order.getMinutes() * 60);
        long nowTime  = TimeUtils.getTimeSecond();
        BookConsultInfo plan  = checkBook(param.getUserId(), nowTime, order.getStartTime(), order.getExpireTime());
        if ((plan != null) && (!order.getOrderNo().equals(plan.getOrderNo())))
        {
            log.info("book create failed: " + plan);

            return ApiResult.failed(10, "确认失败，您在该时段已有预约");
        }

        int ret  = bookService.payCost(param.getUserId(), order.getSurety(), order.getId(), "预约咨询押金");
        if (ret < 0)
        {
            ChatPrivateData info  = new ChatPrivateData();
            info.setContent("余额不足，确认预约失败，请前往充值");
            info.setScheme("xinsu://bean/recharge"); 
            messageService.sendSystemMessage(param.getUserId(), Constant.MSG_TYPE_POPUP, info);

            return ApiResult.failed(10, "余额不足，请先充值");
        }

        order.setContent(param.getContent());
        order.setPayStatus(order.getPayStatus() | Constant.BOOK_PAYED_EARNER);
        order.setStatus(Constant.BOOK_STATUS_PAYED);
        ret = bookService.confirmSheet(order);
        if (ret < 0)
        {
            return ApiResult.failed(10, "确认预约失败，请联系客服");
        }

        //已到开始时间，自动签到
        if ((order.getStartTime() - nowTime) < Constant.TIME_VALUE_10_MINUTES)
        {
            bookService.autoSignIn(order, param.getUserId());
        }

        //发送预约消息
        ChatPrivateData info  = new ChatPrivateData();
        info.setStartTime(order.getStartTime());
        info.setMinutes(order.getMinutes());
        info.setCost(order.getCost());
        info.setOrderNo(order.getOrderNo());
        info.setStatus(order.getStatus());
        info.setContent("咨询服务预约单已确认");
        messageService.sendUserMessage(order.getEarner(), order.getPayer(), Constant.MSG_TYPE_BOOK, info, true);
        messageService.sendOfflineNotice(order.getPayer(), "【预约咨询】", "咨询服务预约单已确认"); 

        return ApiResult.success();
    }

    @ApiOperation("预约变更")
    @PostMapping("/change")
    public ApiResult<Object> change(@RequestBody @Valid BookConfirmParam param) {
        BookConsultInfo order  = bookService.getSheetByOrderNo(param.getOrderNo());
        if (order == null)
        {
            return ApiResult.failed(10, "预约单不存在");
        }

        if (param.getUserId().equals(order.getPayer()))
        {
            return ApiResult.failed(10, "无权限，只有倾听者才能修改预约单");
        }

        if (order.getStatus() > Constant.BOOK_STATUS_START)
        {
            return ApiResult.failed(10, "当前预约服务已结束，不可变更");
        }

        //付费方已签到不可修改
        if ((order.getSignInStatus() & Constant.BOOK_SIGNIN_PAYER) > 0)
        {
            return ApiResult.failed(10, "倾诉者已签到，预约服务不可变更");
        }

        order.setStartTime(param.getTime());
        order.setExpireTime(param.getTime() + order.getMinutes() * 60);
        long nowTime  = TimeUtils.getTimeSecond();
        BookConsultInfo plan  = checkBook(param.getUserId(), nowTime, order.getStartTime(), order.getExpireTime());
        if ((plan != null) && (!order.getOrderNo().equals(plan.getOrderNo())))
        {
            log.info("book create failed: " + plan);

            return ApiResult.failed(10, "变更失败，您在该时段已有预约");
        }

        order.setContent(param.getContent());
        order.setRemark("变更预约");
        order.setSignInStatus(Constant.BOOK_SIGNIN_NONE);
        order.setStatus(order.getStatus() == Constant.BOOK_STATUS_START ? Constant.BOOK_STATUS_PAYED : order.getStatus());
        if (bookService.changeSheet(order) < 0)
        {
            return ApiResult.failed(10, "变更预约失败，请联系客服");
        }

        //已到开始时间，自动签到
        if ((order.getStartTime() - nowTime) < Constant.TIME_VALUE_10_MINUTES)
        {
            bookService.autoSignIn(order, param.getUserId());
        }

        //发送预约消息
        ChatPrivateData info  = new ChatPrivateData();
        info.setStartTime(order.getStartTime());
        info.setMinutes(order.getMinutes());
        info.setCost(order.getCost());
        info.setOrderNo(order.getOrderNo());
        info.setStatus(order.getStatus());
        info.setContent("咨询预约单已变更");
        messageService.sendUserMessage(order.getEarner(), order.getPayer(), Constant.MSG_TYPE_BOOK, info, true); 
        messageService.sendOfflineNotice(order.getPayer(), "【预约咨询】", "咨询预约单已变更");

        return ApiResult.success();
    }

    @ApiOperation("预约服务签到")
    @PostMapping("/signIn")
    public ApiResult<Object> signIn(@RequestBody @Valid BookSignInParam param) {
        BookConsultInfo order  = bookService.getSheetByOrderNo(param.getOrderNo());
        if (order == null)
        {
            return ApiResult.failed(10, "预约单不存在");
        }

        if (order.getStatus() > Constant.BOOK_STATUS_START)
        {
            return ApiResult.failed(10, "当前预约服务已结束，不可签到");
        }

        long nowTime  = TimeUtils.getTimeSecond();
        //当前时间超过预定时间段则不可签到
        if (nowTime > order.getExpireTime())
        {
            return ApiResult.failed(10, "当前预约服务已到期，不可签到");
        }

        if ((order.getStartTime() - nowTime) > Constant.TIME_VALUE_10_MINUTES)
        {
            return ApiResult.failed(10, "预定开始时间前10分钟才能签到");
        }

        int lastStatus  = order.getSignInStatus();
        if (param.getUserId().equals(order.getPayer()))
        {
            if ((order.getSignInStatus() & Constant.BOOK_SIGNIN_PAYER) > 0)
            {
                return ApiResult.failed(10, "已签到");
            }
            else
            {
                order.setSignInStatus(order.getSignInStatus() | Constant.BOOK_SIGNIN_PAYER);
            }
        }
        else
        {
            if ((order.getSignInStatus() & Constant.BOOK_SIGNIN_EARNER) > 0)
            {
                return ApiResult.failed(10, "已签到");
            }
            else
            {
                order.setSignInStatus(order.getSignInStatus() | Constant.BOOK_SIGNIN_EARNER);
            }

            //收益方迟到不能签到，需要重新预约
            if (nowTime > order.getStartTime())
            {
                return ApiResult.failed(10, "您已迟到，请先结束订单并与用户重新预约");
            }
        }

        if (order.getSignInStatus() == Constant.BOOK_SIGNIN_BOTH)
        {
            order.setStatus(Constant.BOOK_STATUS_START);
        }

        //双方同时签到，后执行的一方可能会失败
        int ret = bookService.signInSheet(order, lastStatus);
        if (ret < 0)
        {
            //重新获取订单最新状态
            order  = bookService.getSheetByOrderNo(order.getOrderNo());
            lastStatus  = order.getSignInStatus();
            if (param.getUserId().equals(order.getPayer()))
            {
                order.setSignInStatus(order.getSignInStatus() | Constant.BOOK_SIGNIN_PAYER);
            }
            else
            {
                order.setSignInStatus(order.getSignInStatus() | Constant.BOOK_SIGNIN_EARNER);
            }

            if (order.getSignInStatus() == Constant.BOOK_SIGNIN_BOTH)
            {
                order.setStatus(Constant.BOOK_STATUS_START);
            }

            ret = bookService.signInSheet(order, lastStatus);
            if (ret < 0)
            {
                return ApiResult.failed(10, "签到失败，请联系客服");
            }
        }

        long recverId  = (order.getPayer().equals(param.getUserId())) ? order.getEarner() : order.getPayer();
        //推送消息
        ChatPrivateData info  = new ChatPrivateData();
        info.setStartTime(order.getStartTime());
        info.setMinutes(order.getMinutes());
        info.setCost(order.getCost());
        info.setOrderNo(order.getOrderNo());
        info.setStatus((nowTime < order.getStartTime()) ? Constant.BOOK_STATUS_PAYED : Constant.BOOK_STATUS_START);
        info.setContent("预约的咨询对方已签到");
        messageService.sendUserMessage(param.getUserId(), recverId, Constant.MSG_TYPE_BOOK, info, true); 
        messageService.sendOfflineNotice(recverId, "温馨提示", "您有预约的咨询服务即将开始，请准时上线");

        return ApiResult.success();
    }

    @ApiOperation("预约服务结束")
    @PostMapping("/finish")
    public ApiResult<Object> finish(@RequestBody @Valid BookFinishParam param) {
        BookConsultInfo order  = bookService.getSheetByOrderNo(param.getOrderNo());
        if (order == null)
        {
            return ApiResult.failed(10, "预约单不存在");
        }

        if (order.getStatus() > Constant.BOOK_STATUS_START)
        {
            return ApiResult.failed(10, "当前预约单已结束");
        }

        long nowTime  = TimeUtils.getTimeSecond();
        //服务已开始
        if ((order.getStatus() == Constant.BOOK_STATUS_START) || ((order.getStartTime() < nowTime)) && (order.getStartTime() > 0))
        {
            //服务已经开始只能由收费方结束订单
            if (param.getUserId().equals(order.getPayer()))
            {
                return ApiResult.failed(10, "服务已开始，您无结束权限，请联系倾听者修改预约");
            }

            //服务进行中并且只有收益方签到的情况下不允许结束订单
            if ((order.getSignInStatus() == Constant.BOOK_SIGNIN_EARNER)  && (nowTime < order.getExpireTime()))
            {
                return ApiResult.failed(10, "倾诉者未签到，不允许结束服务");
            }

            order.setFinishStatus(Constant.BOOK_FINISH_EARNER);
            order.setRemark("收费方结束服务");
            order.setStatus(Constant.BOOK_STATUS_STOP);
            order.setStopTime(nowTime);
        }
        else
        {
            if ((order.getStartTime() > 0) && ((order.getStartTime() - nowTime) < Constant.TIME_VALUE_01_HOURS))
            {
                return ApiResult.failed(10, "距离预定开始时间已不足一小时，无法取消");
            }

            if (param.getUserId().equals(order.getPayer()))
            {
                order.setFinishStatus(Constant.BOOK_FINISH_PAYER);
                order.setRemark("付费方取消预约");
            }
            else
            {
                order.setFinishStatus(Constant.BOOK_FINISH_EARNER);
                order.setRemark("收费方取消预约");
            }

            order.setStatus(Constant.BOOK_STATUS_DROP);
            order.setStopTime(nowTime);
        }          
        
        int ret = bookService.finishSheet(order);
        if (ret == 0)
        {
            //发送对方发送通知
            long recverId   = (order.getPayer().equals(param.getUserId())) ? order.getEarner() : order.getPayer();
            ChatPrivateData info  = new ChatPrivateData();
            info.setStartTime(order.getStartTime());
            info.setMinutes(order.getMinutes());
            info.setCost(order.getCost());
            info.setOrderNo(order.getOrderNo());
            info.setStatus(order.getStatus());
            info.setContent("咨询服务已结束");
            messageService.sendUserMessage(param.getUserId(), recverId, Constant.MSG_TYPE_BOOK, info, true);
        }

        return ApiResult.success();
    }

    @ApiOperation("预约查询")
    @PostMapping("/query")
    public ApiResult<Object> query(@RequestBody @Valid BookQueryParam param) {
        BookConsultInfo order  = bookService.getSheetByOrderNo(param.getOrderNo());
        if (order == null)
        {
            return ApiResult.failed(10, "预约单不存在");
        }

        if ((param.getSerial() < 26) && (param.getBranch() > 200))
        {
            return ApiResult.success(order);
        }

        String[] rules  = {
            "1、预约需要支付定金，爽约者定金只退50%",
            "2、所付定金仅为预约时段内的纯文字聊天每分钟的收费价格，若咨询时段内仅纯文字聊天不需另外付费，语音通话将根据实际收费标准实时付费",
            "3、所预约的咨询服务以双方签到为开始，截止预约时段结束仍未签到者视为爽约。未爽约者定金全额退款，并获得爽约者所支付定金50%的补偿",
            "4、咨询服务以预约的时段计费。咨询服务开始后若提前结束，按实际服务时长计费",
            "5、距预约服务开始前十分钟可签到，不足一小时不可取消"
        };
        
        JSONObject json  = new JSONObject();
        json.set("order", order);
        json.set("rules", rules);;

        return ApiResult.success(json);
    }    

    @ApiOperation("查询预约记录")
    @PostMapping("/record")
    public ApiResult<Object> record(@RequestBody @Valid BookRecordParam param) {
        List<BookConsultInfo> recordList  = bookService.getRecord(param.getUserId(), param.getPage(), param.getStart(), param.getStop());
        
        JSONObject json  = new JSONObject();
        json.set("recordList", recordList);

        return ApiResult.success(json);
    }    
}
